/**
 *
 */
package com.angel.annotation.finders;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;

import com.angel.annotation.exceptions.AnnotationManagerException;
import com.angel.annotation.interfaces.AnnotationObjectFinder;

/**
 *
 * @author William
 *
 */
public class AnnotationConstructorFinder implements AnnotationObjectFinder{

	private static AnnotationObjectFinder instance;

	private AnnotationConstructorFinder(){
		super();
	}

	public static synchronized AnnotationObjectFinder getInstance(){
		if(instance == null){
			instance = new AnnotationConstructorFinder();
		}
		return instance;
	}

	@SuppressWarnings("unchecked")
	public <T extends Annotation> Annotation findAnnotationAt(Object object, Class<T> annotationClass) {
		Annotation annotation = null;
		int quantity = 0;

		Constructor<T>[] constructors = (Constructor<T>[]) object.getClass().getConstructors();
		if(constructors != null && constructors.length > 0){
			for(Constructor constructor: constructors){
				annotation = constructor.getAnnotation(annotationClass);
				if( annotation != null){
					quantity++;
				}
			}
		}
		if(quantity > 1){
			throw new AnnotationManagerException("Object has more than one annotation implementation for [" + annotationClass.getCanonicalName() + "].");
		}
		return annotation;
	}

	@SuppressWarnings("unchecked")
	public <T extends Annotation> Object findTargetObjectFor(Object object, Class<T> annotationClass) {
		Annotation annotation = this.findAnnotationAt(object, annotationClass);
		Object targetObject = null;
		if(annotation != null){
			Constructor<T>[] constructors = (Constructor<T>[]) object.getClass().getConstructors();
			if(constructors != null && constructors.length > 0){
				for(Constructor<T> constructor: constructors){
					annotation = constructor.getAnnotation(annotationClass);
					if( annotation != null){
						targetObject = constructor;
						break;
					}
				}
			}
		}
		return targetObject;
	}

}
